import React from 'react';
React.useLayoutEffect = React.useEffect;
import { StaticRouter } from 'react-router-dom';
import { renderToString } from 'react-dom/server';
import { stores } from './stores/index'; // ...
import { Provider } from 'mobx-react';
import Routers from './Routers';
import { routes } from './routes.config';
import cloneDeep from 'lodash/cloneDeep';

/**
 * 需要暴露的方法
 *
 * // 覆盖服务端程序
 * coverServerDOM();
 *
 * // 获取scripts注入的数据
 * getSSRData();
 *
 * // 注入路由配置
 * injectRoutePath(routes);
 * return new routes
 *
 * // route, props
 * renderToHTML(route, props)
 * 页面模块转换成html
 *
 */

// renderToHTML 不能修改原始routes
const routesClone = cloneDeep(routes);

async function renderToHTML(route, props) {
  let scripts = null;
  let component = null;
  if (!route.component.preload) {
    component = route.component;
  } else {
    component = await route.component.preload().then(res => res.default);
  }
  if (component.ssrData) {
    const res = await component.ssrData(route);
    try {
      component.defaultProps = { ...res };
      scripts = `<script>var ssrData_${component.wrappedComponent.name} = ${JSON.stringify(res)};</script>`;
    } catch (e) {
      console.error('static ssData 必须返回一个对象');
      return '<div style="color:red;">ssData 必须返回一个对象</div>';
    }
  } else {
    // 如果没有异步数据
    scripts = '';
  }
  const shtml = renderToString(
    <Provider {...stores}>
      <Routers Router={StaticRouter} routes={routesClone} location={props.location} context={props.context} />
    </Provider>
  );
  return { shtml, scripts };
}

// 修改原始routes
async function injectRoutePath(routesArr, path = '') {
  routesArr.forEach(route => {
    route.path = path + route.path;
    if (route.routes) {
      injectRoutePath(route.routes, route.path);
    }
  });
}

injectRoutePath(routes);

export { routes, renderToHTML };
